package com.basin.micro.gateway.handler;

import cn.dev33.satoken.stp.StpInterface;
import com.basin.dubbo.AuthDubboService;
import com.basin.dubbo.pojo.UserPermissionInfo;
import com.basin.micro.gateway.prop.BasinAuthProps;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.List;

/**
 * @author: Sam ZHONG | sammy1997@aliyun.com
 */
@Component
@Slf4j
public class AuthHandler implements StpInterface {
    private static final String PERM = "perm";
    private static final String ROLE = "role";

    @Resource
    private BasinAuthProps basinAuthProps;
    @Resource
    private RedissonClient redissonClient;
    @DubboReference
    private AuthDubboService authDubboService;

    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        return this.get(loginId, PERM);
    }

    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        return this.get(loginId, ROLE);
    }

    /**
     * 获取用户权限数据集
     *
     * @param loginId 用户id
     * @param wayType 类型
     * @return 结果集
     */
    private List<String> get(Object loginId, String wayType) {
        String authUserPermissionsRedisKey = this.basinAuthProps.getAuthUserPermissionsRedisKey() + ":" + loginId;
        RBucket<UserPermissionInfo> bucket = this.redissonClient.<UserPermissionInfo>getBucket(authUserPermissionsRedisKey);
        UserPermissionInfo curPermInfo = bucket.get();
        boolean exists = bucket.isExists();
        if (!exists) {
            curPermInfo = this.authDubboService.getUserPermissionInfo(loginId);
            this.redissonClient.<UserPermissionInfo>getBucket(authUserPermissionsRedisKey).setAsync(curPermInfo, Duration.ofMinutes(5));
        };
        if (PERM.equals(wayType)) {
            return curPermInfo.getPermissions();
        } else {
            return curPermInfo.getRoles();
        }
    }
}
